package ezonsport.android.service.webservice;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;





public class WebServiceMdi  implements IWebServiceMdi{	
	private String url;	
	private String nameSpace;
	private String methodName;
	private String soapAction;
	@Override
	public String getUrl() {
		return url;
	}
	@Override
	public void setUrl(String url) {
		this.url = url;
	}
	@Override
	public String getNameSpace() {
		return nameSpace;
	}
	@Override
	public void setNameSpace(String nameSpace) {
		this.nameSpace = nameSpace;
	}
	@Override
	public String getMethodName() {
		return methodName;
	}
	@Override
	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}
	@Override
	public String getSoapAction() {
		return soapAction;
	}
	@Override
	public void setSoapAction(String soapAction) {
		this.soapAction = soapAction;
	}
	@Override
	public <T> T run(Class<T> clazz) {	
		return run(clazz,new ArrayList<PropertyInfo>());
	}

	



	@Override
	public <T> T run(Class<T> clazz, PropertyInfo property) {
		List<PropertyInfo> properties=new ArrayList<PropertyInfo>();
		properties.add(property);
		return run(clazz,properties);
	}
	@Override
	public <T> T run(Class<T> calzz, List<PropertyInfo> properties) {
		SoapObject rpc = new SoapObject(nameSpace, methodName);
		if(properties!=null)
		{
			for(PropertyInfo property : properties)
				rpc.addProperty(property);
		}
		if(soapAction==null)
		{
			soapAction=nameSpace+"/"+methodName;
		}
		
		HttpTransportSE ht = new HttpTransportSE(url);
		ht.debug = true;
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.setOutputSoapObject(rpc);
		try {
			ht.call(soapAction, envelope);
		   SoapObject	 detail = (SoapObject) envelope.getResponse();
            T obj = (T) copy(calzz,detail);
		    return obj;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		return null;
	}
	
	//���÷������ ���� soapObject
	public  <T> Object copy(Class<T> clazz, SoapObject soapObject) throws Exception {
        // ��ö��������
        Class<?> classType = clazz;
        System.out.println("Class:" + classType.getName());
        // ͨ��Ĭ�Ϲ��췽������һ���µĶ���
        Object objectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
        // ��ö������������
        Field fields[] = classType.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];           
            String fieldName = field.getName();
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            // ��ú����Զ�Ӧ��setXXX()����������
            String setMethodName = "set" + firstLetter + fieldName.substring(1);
            // ��ú����Զ�Ӧ��setXXX()����
            Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()});
      
            System.out.println("fieldType" + ":" +  field.getType());
        
          if(field.getType().equals(List.class))
          {
        	 String str=field.getGenericType().toString();      
        	 System.out.println("fieldType is List" );
        	 List  ChildObjectCopy=new ArrayList();  
        	 System.out.println("this is: "+ ChildObjectCopy.getClass());        	  
        	
        	 //��ȡ�� list ��װ������
        	  String realType=str.substring(str.indexOf('<')+1, str.indexOf('>'));
        	
        	  for(int k=0;k<soapObject.getPropertyCount();k++)
        	  {
        		 
        		try {
        			SoapObject childSoapObject=(SoapObject) soapObject.getProperty(k) ; 
           	     if(realType.contains(childSoapObject.getName()))
           	     {
           	    	 Class<?> clz=	 Class.forName(realType);
           	    	 Object value= copy(clz,childSoapObject) ;
           	    	 ChildObjectCopy.add(value);
           	     }
					
				} catch (Exception e) {
					//System.out.println(e.getMessage());
				} 
        	  }
        	setMethod.invoke(objectCopy,ChildObjectCopy);
          }
          else if(!field.getType().isPrimitive() &&!isJavaClass(field.getType()))
          {
        	  field.getType().getPackage().getName().startsWith("java");
        	  System.out.println("fieldType is  not a primitive" );
        	  System.out.println("fieldType" + ":" +  field.getType()   +isJavaClass(field.getType()) );
        	  SoapObject soapObjectNext=(SoapObject) soapObject.getProperty(fieldName);
        	  if(soapObjectNext!=null)
        	  {
        	 Object value= copy(field.getType(),soapObjectNext) ;
        	 setMethod.invoke(objectCopy, new Object[]{value});
        	  }
          }
          else{
        	  Object  value=  soapObject.getProperty(fieldName);	  
             String args =  value.toString();
               //��string ���͵�ֵת��Ϊ�������
                Object realValue=  DataTypeConverter.converter(args, field.getType());    
                // ���ÿ��������setXXX()����
              	setMethod.invoke(objectCopy, new Object[]{realValue});
          }     
        }
        return objectCopy;
        }    
	
	public static boolean isJavaClass(Class<?> clz) {  
	    return	clz.getPackage().getName().startsWith("java"); 
	  }  
}


	
	



